package org.phantom.securityframework.local;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSession;
import org.phantom.securityframework.api.Account;
import org.phantom.securityframework.api.Permission;
import org.phantom.securityframework.api.RoleManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.phantom.securityframework.api.domain.Group;
import org.phantom.securityframework.api.domain.Role;
import org.phantom.securityframework.api.util.AuthUtil;

@Service
@Transactional
public class RoleManagerLocalImpl implements RoleManager {

	@Resource
	private SqlSession session = null;
	
	@Override
	public Role add(Role role) {
		if(role==null)return null;
		session.insert("org.phantom.securityframework.RoleMapper.insertRole", role);
		return role;
	}

	@Override
	public Role modify(Role role) {
		if(role.getId()==null || role.getId().intValue()==0){
			throw new RuntimeException("roleId can not be null!");
		}
		session.update("org.phantom.securityframework.RoleMapper.updateRole",role);
		return role;
	}

	@Override
	public Role remove(Role role) {
		if(role.getId()==null || role.getId().intValue()==0){
			throw new RuntimeException("roleId can not be null!");
		}
		session.delete("org.phantom.securityframework.RoleMapper.removeRole", role);
		role.setId(0);
		return role;
	}

	@Override
	public Role remove(Integer roleId) {
		if(roleId==null || "".equals(roleId)){
			throw new RuntimeException("roleId can not be null!");
		}
		return this.remove(this.get(roleId));
	}

	@Override
	public Role get(Integer roleId) {
		if(roleId==null || "".equals(roleId)){
			throw new RuntimeException("roleId can not be null!");
		}
		return (Role) session.selectOne("org.phantom.securityframework.RoleMapper.getRoleById", roleId);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Role> list() {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("platformId", AuthUtil.getPlatformId());
		return session.selectList("org.phantom.securityframework.RoleMapper.list",params);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Role> list(Map<String, Object> params) {
		if(params==null || params.size()<=0)
			return this.list();
	
		if(!params.containsKey("platformId")){
			params.remove("platformId");
			params.put("platformId", AuthUtil.getPlatformId());
		}
		return session.selectList("org.phantom.securityframework.RoleMapper.list", params);
	}

	@Override
	public void relAccountRole(Account a, Role[] roles) {

		org.phantom.securityframework.api.domain.Account account = (org.phantom.securityframework.api.domain.Account) a;
		List<Integer> list = new ArrayList<Integer>();
		for (Role r : roles) {
			list.add(r.getId());
		}
		this.relAccountRole(account.getId(), list.toArray(new Serializable[]{}));
	}

	@Override
	public void relAccountRole(Account a, Serializable[] roleIds) {

		org.phantom.securityframework.api.domain.Account account = (org.phantom.securityframework.api.domain.Account) a;
		this.relAccountRole(account.getId(), roleIds);
	}

	@Override
	public void relAccountRole(Serializable accountId, Serializable[] roleIds) {
		if(accountId==null){
			throw new RuntimeException("accountId can not be null!");
		}
		Map<String,Integer> params = new HashMap<String,Integer>();
		for (Serializable id : roleIds) {
			params.put("roleId",(Integer)id);
			params.put("accountId", (Integer) accountId);
			session.insert("org.phantom.securityframework.RoleMapper.relAccountRole",params);
			params.clear();
		}
	}

	@Override
	public void unrelAccountRole(Account a, Role[] roles) {

		org.phantom.securityframework.api.domain.Account account = (org.phantom.securityframework.api.domain.Account) a;
		List<Integer> list = new ArrayList<Integer>();
		for (Role r : roles) {
			list.add(r.getId());
		}
		this.unrelAccountRole(account.getId(), list.toArray(new Serializable[]{}));
	}
	@Override
	public void unrelAccountRole(Account a, Serializable[] roleIds) {
		org.phantom.securityframework.api.domain.Account account = (org.phantom.securityframework.api.domain.Account) a;
		this.unrelAccountRole(account.getId(), roleIds);
	}
	@Override
	public void unrelAccountRole(Serializable accountId, Serializable[] roleIds) {
		Map<String, Object> params = new HashMap<String, Object>();
		for (Serializable roleId : roleIds) {
			params.put("accountId", accountId);
			params.put("roleId", roleId);
			session.delete("org.phantom.securityframework.RoleMapper.unrelAccountRole",params);
			params.clear();
		}
	}

	@Override
	public void relGroupRole(Group group, Role[] role) {
		List<Integer> list = new ArrayList<Integer>();
		for (Role r : role) {
			list.add(r.getId());
		}
		this.relGroupRole(group.getId(), list.toArray(new Serializable[]{}));
	}

	@Override
	public void relGroupRole(Group group, Serializable[] roleIds) {
		this.relGroupRole(group.getId(), roleIds);
	}
	
	@Override
	public void relGroupRole(Serializable groupId, Serializable[] roleIds) {
		if(groupId==null){
			throw new RuntimeException("groupId can not be null!");
		}
		Map<String,Integer> params = new HashMap<String,Integer>();
		for (Serializable id : roleIds) {
			params.put("groupId", (Integer) groupId);
			params.put("roleId",(Integer)id);
			session.insert("org.phantom.securityframework.RoleMapper.relGroupRole",params);
			params.clear();
		}
	}

	@Override
	public void unrelGroupRole(Group group, Role[] role) {

		List<Integer> list = new ArrayList<Integer>();
		for (Role r : role) {
			list.add(r.getId());
		}
		this.unrelGroupRole(group.getId(), list.toArray(new Serializable[]{}));
	}

	@Override
	public void unrelGroupRole(Group group, Serializable[] roleIds) {
		this.unrelGroupRole(group.getId(), roleIds);
	}

	@Override
	public void unrelGroupRole(Serializable groupId, Serializable[] roleIds) {
		Map<String, Object> params = new HashMap<String, Object>();
		for (Serializable roleId : roleIds) {
			params.put("groupId", groupId);
			params.put("roleId", roleId);
			session.delete("org.phantom.securityframework.RoleMapper.unrelGroupRole",params);
			params.clear();
		}
	}

	@Override
	public Integer count() {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("platformId", AuthUtil.getPlatformId());
		return (Integer) session.selectOne("org.phantom.securityframework.RoleMapper.count",params);
	}

	@Override
	public Integer count(Map<String, Object> params) {
		if(params==null || params.size()<=0){
			return this.count();
		}
		if(params.containsKey("platformId")){
			params.remove("platformId");
			params.put("platformId", AuthUtil.getPlatformId());
		}
		return (Integer) session.selectOne("org.phantom.securityframework.RoleMapper.count",params);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Permission> permissions(Role role) {
		return session.selectList("org.phantom.securityframework.RoleMapper.listRolePermission",role);
	}
}
